$MOD186
NAME Main
; Main program for uPD70208 microcomputer system
;
; Author: 	Dr Tay Teng Tiow
; Address:     	Department of Electrical Engineering 
;         	National University of Singapore
;		10, Kent Ridge Crescent
;		Singapore 0511.	
; Date:   	6th September 1991
;
; This file contains proprietory information and cannot be copied 
; or distributed without prior permission from the author.
; =========================================================================
;User Main Programm


;public means you want other modules to access this routine
;API
;local function:

public  timer2_action ;timer2_action is the action taken by the programme when there is timer 2 interrupt

;external function to call:
;in serial.asm
extrn	print_char:far, print_2hex:far
;in 80188.asm
extrn iodefine:far
;in timer2.asm
extrn   start_timer2:far
;in LCD.asm
extrn  write_char_to_LCD:far
extrn LCD_display_now:far
extrn write_string_to_LCD:far

extrn Serial_Get_data:far
extrn Serial_check_Received_status:far
extrn Serial_send_protocol:far

$include (PPI.inc)  ;stores impt constant to configure PPI
$include (Serial.inc)

STACK_SEG	SEGMENT
		DB	256 DUP(?)
	TOS	LABEL	WORD
STACK_SEG	ENDS


DATA_SEG	SEGMENT ;remember to put 10,13 in front of the string when you declare string in data segment
	TIMER0_MESS	DB	10,13,'Toyota',0;ascii 10 corresponds to new line character and ascii 13 corresponds to carriage return
	T_COUNT		DB	2FH  ;initialise period to send message to hyperterminal is 1.42s. So for every 2FH number of timer interrupt, it will send to hyperterminal
	T_COUNT_SET	DB	2FH
	REC_MESS	DB	10,13,'Cost: S$110,000',0 
	Serial_RBuffer DB 50 Dup(0) ;data pass by serial  
	Price_display DB 10,13, 'Price: $',7 Dup(0),0 
	LCD_Dollars_in_char DB 4 Dup(0)
	LCD_Cents_in_char DB 2 Dup (0)
	
DATA_SEG	ENDS


CODE_SEG	SEGMENT

	PUBLIC		START

ASSUME	CS:CODE_SEG, SS:STACK_SEG

START:
;initialize stack area
		MOV	AX,STACK_SEG		
		MOV	SS,AX
		MOV	SP,TOS

; Initialize the on-chip pheripherals
		CALL	FAR PTR	IODEFINE
		


		
; ^^^^^^^^^^^^^^^^^  Start of User Main Routine  ^^^^^^^^^^^^^^^^^^
  ;  call start_timer2 ;start timer 2
    STI ;enable global interrupt 
     MOV BX, DATA_SEG
	MOV ES, BX
	MOV DS, BX
	
;	MOV SI, offset TIMER0_MESS
;	ADD SI, 2
;	MOV AL, 1
	
;	call far ptr write_string_to_LCD

 ;   MOV SI, offset REC_MESS
;	ADD SI, 2
;	MOV AL, 2
	
;	call far ptr write_string_to_LCD
;	call far ptr LCD_display_now	

	

NEXT:    
	
  call far ptr Serial_check_Received_status
  ;call far ptr print_2hex
  cmp AL, Serial_has_packet_in_RBuffer 
  JNE NEXT
  ;check if the packet is type1
  cmp AH, 1
  JNE Main_check_other_type
  ;if packet is type 1,
  
  ;send type 2 acknowledgement
  Mov AL, 2
  call far ptr Serial_send_protocol
  ;clear SRbuffer
  call far ptr Main_copy_from_SRbuffer
  
  
  jmp NEXT
  
  Main_check_other_type:
  cmp AH, 3
  JNE Main_clear_packet     ;clear the packet in the buffer since it is of different ID
  ;if packet is type 3,
  
  ;send type 4 acknowledgement
  Mov AL, 4
  call far ptr Serial_send_protocol
  
  ;copy from Sbuffer
  call far ptr Main_copy_from_SRbuffer
  

  ;display the product name and its price on LCD
  call far ptr Main_write_product_name_to_LCD
  call far ptr Main_write_product_price_to_LCD
 ; MOV SI, offset Price_display
 ; Add SI,2
 ; MOV AL,2
 ; call far ptr write_string_to_LCD
  call far ptr LCD_display_now
  
  
  jmp NEXT
  
  Main_clear_packet:       ;clear packet from buffer by taking out the packet because it is invalid
  
  call far ptr Main_copy_from_SRbuffer
  

  
  
  
  ;MOV SI, offset Serial_RBuffer
  ;MOV AL, 1
  
  ;call far ptr write_string_to_LCD
  
  ;MOV AL, 2
  ;MOV SI, offset Serial_RBuffer
  ;call far ptr write_string_to_LCD
  
  ;call far ptr LCD_display_now
  
  
  

JMP NEXT


Main_copy_from_SRbuffer PROC FAR

  push BX
  push DI
  push ES
  
  ;copy from serial buffer
  MOV BX, DATA_SEG
  MOV ES,BX
  MOV DI, offset Serial_RBuffer
  
  call far ptr Serial_Get_data

  
  
  pop ES
  pop DI
  pop BX
  ret

Main_copy_from_SRbuffer endp

; ^^^^^^^^^^^^^^^ End of User main routine ^^^^^^^^^^^^^^^^^^^^^^^^^


Main_write_product_name_to_LCD PROC FAR
	push ES
	push BX
	push SI
	push DS
	
	Mov BX,DATA_SEG
	Mov DS, BX
	Mov ES, BX
	
	
	MOV AL,1
	MOV SI, offset Serial_RBuffer
	ADD SI, 1 ;display on first line
	
	call far ptr write_string_to_LCD

	pop DS
	pop SI
	pop BX
	pop ES
	
	ret

Main_write_product_name_to_LCD endp


Main_write_product_price_to_LCD proc far
	push ES
	push BX
	push SI
	
	
	
	Mov BX,DATA_SEG
	
	Mov ES, BX

	
	
	call far ptr Main_convert_dollars_to_char
	call far ptr Main_convert_cents_to_char
	
	call far ptr Main_copying_dollars_cents_into_variable
	;write the price to LCD
	MOV AL, 2 ;display on second line
	Mov SI, offset Price_display
	Add SI,2
	call far ptr write_string_to_LCD
	
	
	
	
	
	

	
	pop SI
	pop BX
	pop ES
	ret
Main_write_product_price_to_LCD endp

Main_copying_dollars_cents_into_variable proc far
	push SI
	push CX
	
	push DI
	push BX
	push AX
	

	
	MOV DI, offset Price_display
	ADD DI,10
	;copy dollars first
	Mov SI, offset LCD_Dollars_in_char
	MOV CX,4
	
	Main_copying_dollars_loop:
	Mov AL, [SI]
	cmp AL, ' '
	je Main_goto_copying_loop
	
	Mov [DI],AL
	inc DI
	
	Main_goto_copying_loop:
	inc SI
	loop Main_copying_dollars_loop
	
	;add decimal
	Mov AL, '.'
	Mov [DI], AL
	inc DI
	
	;copying cents
    Mov SI, offset LCD_Cents_in_char
	Mov CX,2
	
	Main_copying_cents_loop:
	Mov AL, [SI]
	Mov [DI],AL
	inc DI
	inc SI
	loop Main_copying_cents_loop
	
	;add null at the back of the string to indicate end of the string
	Mov AL, 0
	Mov [DI],AL
	
	
	
	pop AX
	pop BX	
	pop DI
	
	pop CX
	pop SI
	ret
	

Main_copying_dollars_cents_into_variable endp

Main_convert_dollars_to_char proc far
	
	push BX
	push SI	
	push AX
	push DX
	push DI
	push CX
	

	
	MOV SI, offset Serial_RBuffer
	ADD SI, 17 ;price
	MOV DI, offset LCD_Dollars_in_char
	ADD DI, 3
	MOV AH, [SI]
	MOV AL, [SI+1]
	
	
	MOV CX,4
	
Main_dollars_convert_loop:	

	
	MOV DX, 0	
	
	MOV BX, 10
	div BX
	
	cmp DX, 0
	jne Main_convert_usual
	cmp AX, 0
	je convert_dollars_actions
	
	Main_convert_usual:
	ADD DX, '0'
	MOV [DI], DL
	;call far ptr print_2Hex
	
	jmp Main_convert_goto_loop
	
	convert_dollars_actions:
	
	;call far ptr print_2Hex
	cmp CX,4
	jne convert_dollars_add_space
	;at a 0 in front if it is less than $1
	Mov DL, '0'
	Mov [DI], DL
	jmp Main_convert_goto_loop
	convert_dollars_add_space:
	Mov DL, ' '
	Mov [DI],DL
	
	Main_convert_goto_loop:
	;call far ptr print_2Hex
	DEC DI
loop Main_dollars_convert_loop
	
	
		
	
	pop CX
	pop DI
	pop DX
	pop AX
	
	pop SI
	pop BX
	
	ret
Main_convert_dollars_to_char endp

Main_convert_cents_to_char PROC FAR

	push BX
	push SI
	push AX
	push DX
	push DI
	push CX
	
	Mov BX,DATA_SEG
	Mov DS, BX
	MOV SI, offset Serial_RBuffer
	ADD SI, 19 ;cents
	MOV DI, offset LCD_Cents_in_char
	ADD DI, 1
	MOV AL, [SI]
	MOV AH, 0
	MOV BX, 10
	
	MOV CX,2
	
Main_cents_convert_loop:	
	
	MOV DX, 0	
	
	MOV BX, 10
	div BX
	ADD DX, '0'
	MOV [DI], DL
	
	DEC DI
loop Main_cents_convert_loop
	
	
		
	
	pop CX
	pop DI
	pop DX
	pop AX
	pop SI
	pop BX
	
	ret
Main_convert_cents_to_char endp

TIMER2_ACTION	PROC	FAR
		PUSH	AX
		PUSH	DS
		PUSH	BX
		PUSH	CX
		PUSH    ES

		MOV	AX,DATA_SEG
		MOV	DS, AX
		
		

		
		
		
		
	
		;DEC	DS:T_COUNT 
		;JNZ	T_NEXT1 ;if there is number of timer interrupt has not reached T_COUNT number, it will not transmit message to hyperterminal
		;MOV	AL,DS:T_COUNT_SET
		;MOV	DS:T_COUNT,AL
		
		;MOV	CX,20   ;number of char to transmit
		;MOV	BX,0H   ;start from index 0
		
		; transmitting message to the hyperterminal
T_NEXT0:
		;MOV	AL,DS:TIMER0_MESS[BX]  ;copy the current character to transmit into AL
		

		;INC	BX                    ;BX++
		;CALL 	FAR PTR PRINT_CHAR  ;prepare the character for transmission ;Since this is string just print character.
		;LOOP	T_NEXT0    ;loop until the CX has reach 0. by using loop, internally it will perform dec CX until CX reaches 0

T_NEXT1:	
		pop ES
		POP	CX
		POP	BX
		POP	DS
		POP 	AX
		RET
TIMER2_ACTION	ENDP


CODE_SEG	ENDS
END
